package drds.global_transaction.api.message_codec;

import java.nio.ByteBuffer;

import drds.global_transaction.api.message_codec.message_codec.Message;
import drds.global_transaction.api.message_codec.message_codec.MessageCodecs;
import drds.global_transaction.api.message_codec.request_and_response.ResponseMessage;
import io.netty.buffer.ByteBuf;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MergeResponseMessage extends Message implements IMergeMessage
{
	private static final long serialVersionUID = -7719219648774528552L;
	@Setter
	@Getter
	public ResponseMessage[] responseMessages;

	@Override
	public short getTypeCode()
	{
		return type_merge_response;
	}

	@Override
	public byte[] encode()
	{
		ByteBuffer byteBuffer = ByteBuffer.allocate(responseMessages.length * 1024);
		byteBuffer.putShort((short) responseMessages.length);
		for (Message message : responseMessages)
		{
			byte[] data = message.encode();
			byteBuffer.putShort(message.getTypeCode());
			byteBuffer.put(data);
		}

		byteBuffer.flip();
		int length = byteBuffer.limit();
		byte[] bytes = new byte[length + 4];
		intToBytes(length, bytes, 0);
		byteBuffer.get(bytes, 4, length);

		return bytes;
	}

	@Override
	public boolean decode(ByteBuf byteBuf)
	{
		int i = byteBuf.readableBytes();
		if (i < 4)
		{
			return false;
		}

		i -= 4;
		int length = byteBuf.readInt();
		if (i < length)
		{
			return false;
		}
		byte[] buffer = new byte[length];
		byteBuf.readBytes(buffer);
		ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
		decode(byteBuffer);
		return true;
	}

	public void decode(ByteBuffer byteBuffer)
	{
		short msgNum = byteBuffer.getShort();
		responseMessages = new ResponseMessage[msgNum];
		for (int idx = 0; idx < msgNum; idx++)
		{
			short typeCode = byteBuffer.getShort();
			IMergedMessage mergedMessage = (IMergedMessage) MessageCodecs.getMessageCodec(typeCode);
			mergedMessage.decode(byteBuffer);
			responseMessages[idx] = (ResponseMessage) mergedMessage;
		}
	}

}
